package com.virgo.login.service;

import cn.hutool.crypto.digest.DigestUtil;
import com.virgo.login.config.LoginConfig;
import com.virgo.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

@Component
public class LoginSecurityService {

	@Autowired
	private RedisService redisService;

	@Autowired
	private LoginConfig loginConfig;

	/**
	 * 检测是否触发登录限制
	 * @param userType String
	 * @param username String
	 * @param ip String
	 * @return Boolean
	 */
	public Boolean checkLogin(String userType, String username, String ip) {
		String userBanKey = DigestUtil.md5Hex(userType + "_user_ban_" + username);
		String ipBanKey = DigestUtil.md5Hex(userType + "_ip_ban_" + ip);
		String userBan = redisService.get(userBanKey);
		String ipBan = redisService.get(ipBanKey);
		return ObjectUtils.isEmpty(userBan) && ObjectUtils.isEmpty(ipBan);
	}

	/**
	 * 密码错误时触发策略
	 * @param userType String
	 * @param username String
	 * @param ip String
	 * @return String
	 */
	public String checkSecurity(String userType, String username, String ip) {
		String userFailKey = DigestUtil.md5Hex(userType+ "_user_fail_" + username);
		String ipFailKey = DigestUtil.md5Hex(userType + "_ip_fail_" + ip);
		String userBanKey = DigestUtil.md5Hex(userType + "_user_ban_" + username);
		String ipBanKey = DigestUtil.md5Hex(userType + "_ip_ban_" + ip);
		String userBan = redisService.get(userBanKey);
		String ipBan = redisService.get(ipBanKey);
		redisService.incr(userFailKey);
		redisService.incr(ipFailKey);
		int userFailNum = Integer.parseInt(redisService.get(userFailKey));
		int ipFailNum = Integer.parseInt(redisService.get(ipFailKey));
		String failNotice = "用户名或密码错误";
		if (userFailNum > (loginConfig.getAccountFailNum() - 1) && userFailNum % loginConfig.getAccountFailNum() == 0) {
			int userShouldBanNum = userFailNum / loginConfig.getAccountFailNum();
			int userBanNum = 0;
			if (!ObjectUtils.isEmpty(userBan)) {
				userBanNum = Integer.parseInt(userBan);
			}
			if (userShouldBanNum > userBanNum) {
				long banSecond = userShouldBanNum * loginConfig.getAccountBanSecond();
				redisService.set(userBanKey,userShouldBanNum+"",banSecond);
				failNotice = "错误次数太多,请稍后再试";
			}
		}
		if (ipFailNum > (loginConfig.getIpFailNum() - 1) && ipFailNum % loginConfig.getIpFailNum() == 0) {
			int userShouldBanNum = ipFailNum / loginConfig.getIpFailNum();
			int userBanNum = 0;
			if (!ObjectUtils.isEmpty(ipBan)) {
				userBanNum = Integer.parseInt(ipBan);
			}
			if (userShouldBanNum > userBanNum) {
				long banSecond = userShouldBanNum * loginConfig.getIpBanSecond();
				redisService.set(ipBanKey,userShouldBanNum+"",banSecond);
				failNotice = "错误次数太多,请稍后再试";
			}
		}
		return failNotice;
	}

	/**
	 * 清除限制措施
	 * @param userType String
	 * @param username String
	 * @param ip String
	 */
	public void clearSecurity(String userType, String username, String ip) {
		String userFailKey = DigestUtil.md5Hex(userType+ "_user_fail_" + username);
		String ipFailKey = DigestUtil.md5Hex(userType + "_ip_fail_" + ip);
		String userBanKey = DigestUtil.md5Hex(userType + "_user_ban_" + username);
		String ipBanKey = DigestUtil.md5Hex(userType + "_ip_ban_" + ip);
		redisService.del(userFailKey);
		redisService.del(ipFailKey);
		redisService.del(userBanKey);
		redisService.del(ipBanKey);
	}
}